using Admin.Application.Common;
using Admin.Application.Dto;
using Admin.Application.Dto.User;
using Admin.Domain.IEvents;
using Admin.Application.Repositories;
using Admin.Domain.Entities;
using Admin.Domain.Repositories;
using Admin.Domain.Events;

namespace Admin.Application.Services;

public class UserService(IRepository<User> userRepository, IRepository<Role> roleRepository, IRepository<Department> departmentRepository, ISystemLogRepository logService) : IUserService
{
    private readonly IRepository<User> _userRepository = userRepository;
    private readonly IRepository<Role> _roleRepository = roleRepository;
    private readonly IRepository<Department> _departmentRepository = departmentRepository;
    private readonly ISystemLogRepository _logService = logService;
    public async Task<Result<string>> AssignRolesToUserAsync(Guid userId, Guid roleId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        var role = await _roleRepository.GetByIdAsync(roleId);
        if (user == null || role == null)
        {
            await _logService.AddAsync($"角色赋予用户失败：用户或角色不存在 - 用户ID：{userId}，角色ID：{roleId}");
            return Result<string>.Fail("用户或角色不存在");
        }

        var isUserUpdated = user.AssignRole(role);
        var isRoleUpdated = role.AddUser(user);
        if (!isUserUpdated || !isRoleUpdated)
        {
            await _logService.AddAsync($"角色赋予用户失败：更新失败 - 用户ID：{userId}，角色ID：{roleId}");
            return Result<string>.Fail("角色赋予用户失败");
        }

        await _userRepository.UpdateAsync(user);
        await _roleRepository.UpdateAsync(role);
        await _logService.AddAsync($"角色赋予用户成功：用户ID：{userId}，角色ID：{roleId}");
        return Result<string>.Success("角色赋予用户成功");
    }

    public async Task<Result<string>> DeleteUserAsync(Guid userId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"删除用户失败：用户不存在 - {userId}");
            return Result<string>.Fail("用户不存在");
        }

        var isUserUpdated = user.DeleteUser();
        if (!isUserUpdated)
        {
            await _logService.AddAsync($"删除用户失败：删除失败 - {userId}");
            return Result<string>.Fail("用户删除失败");
        }

        await _userRepository.UpdateAsync(user);
        await _logService.AddAsync($"删除用户成功：{user.UserName}");
        return Result<string>.Success("用户删除成功");
    }

    public async Task<Result<List<ResUserDto>>> GetPagedUserAsync(int pageIndex, int pageSize)
    {
        if (pageIndex < 0 || pageSize < 0)
        {
            await _logService.AddAsync($"分页查询用户失败：无效的页码或数据条数 - 页码：{pageIndex}，条数：{pageSize}");
            return Result<List<ResUserDto>>.Fail("无效的页码或数据条数");
        }

        var userList = await _userRepository.GetPagedAsync(pageIndex, pageSize);

        var resUserDtoTasks = userList.Select(async u =>
        {
            Department? department = null;
            if (u.DepartmentId.HasValue)
            {
                department = await _departmentRepository.GetByIdAsync(u.DepartmentId.Value);
            }

            var departmentName = department?.DepartmentName;

            return new ResUserDto(
                u.Id,
                u.UserName,
                u.IsActive,
                u.Description,
                departmentName,
                string.Join(",", u.Roles.Select(r => r.RoleName))
            );
        });

        var resUserDtoList = await Task.WhenAll(resUserDtoTasks);

        await _logService.AddAsync($"分页查询用户成功：页码 {pageIndex}，条数 {pageSize}");
        return Result<List<ResUserDto>>.Success([.. resUserDtoList]);
    }

    public async Task<Result<ResUserDto?>> GetUserByIdAsync(Guid userId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"查询用户失败：用户不存在 - {userId}");
            return Result<ResUserDto?>.Fail("用户不存在");
        }

        Department? department = null;
        if (user.DepartmentId.HasValue)
        {
            department = await _departmentRepository.GetByIdAsync(user.DepartmentId.Value);
        }

        var departmentName = department?.DepartmentName;

        var resUserDto = new ResUserDto(
                user.Id,
                user.UserName,
                user.IsActive,
                user.Description,
                departmentName,
                string.Join(",", user.Roles.Select(r => r.RoleName))
            );

        await _logService.AddAsync($"查询用户成功：{user.UserName}");
        return Result<ResUserDto?>.Success(resUserDto);
    }

    public async Task<Result<string>> RemoveRolesFromUserAsync(Guid userId, Guid roleId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        var role = await _roleRepository.GetByIdAsync(roleId);
        if (user == null || role == null)
        {
            await _logService.AddAsync($"角色移除用户失败：用户或角色不存在 - 用户ID：{userId}，角色ID：{roleId}");
            return Result<string>.Fail("用户或角色不存在");
        }

        var isUserUpdated = user.RemoveRole(role);
        var isRoleUpdated = role.RemoveUser(user);
        if (!isUserUpdated || !isRoleUpdated)
        {
            await _logService.AddAsync($"角色移除用户失败：更新失败 - 用户ID：{userId}，角色ID：{roleId}");
            return Result<string>.Fail("角色移除用户失败");
        }

        await _userRepository.UpdateAsync(user);
        await _roleRepository.UpdateAsync(role);
        await _logService.AddAsync($"角色移除用户成功：用户ID：{userId}，角色ID：{roleId}");
        return Result<string>.Success("角色移除用户成功");
    }

    public async Task<Result<string>> UpdateIsActive(Guid userId, ActiveDto activeDto)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"更新用户启用状态失败：用户不存在 - {userId}");
            return Result<string>.Fail("用户不存在");
        }

        bool isUserUpdated;
        if (activeDto.IsActive)
        {
            isUserUpdated = user.EnableUser();
        }
        else
        {
            isUserUpdated = user.DisableUser();
        }

        if (!isUserUpdated)
        {
            await _logService.AddAsync($"更新用户启用状态失败：更新失败 - {userId}");
            return Result<string>.Fail("用户启用状态更新失败");
        }

        await _userRepository.UpdateAsync(user);
        await _logService.AddAsync($"更新用户启用状态成功：{user.UserName}");
        return Result<string>.Success("用户启用状态更新成功");
    }

    public async Task<Result<string>> UpdateUserDepartmentIdAsync(Guid userId, Guid? departmentId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"更新用户部门失败：用户不存在 - {userId}");
            return Result<string>.Fail("用户不存在");
        }

        if (user.DepartmentId.HasValue)
        {
            var originalDepartment = await _departmentRepository.GetByIdAsync(user.DepartmentId.Value);
            if (originalDepartment != null)
            {
                bool isRemoved = originalDepartment.RemoveUser(user);
                if (!isRemoved)
                {
                    await _logService.AddAsync($"从原部门移除用户失败：用户ID {userId}，部门ID {user.DepartmentId}");
                    return Result<string>.Fail("从原部门移除用户失败");
                }
                await _departmentRepository.UpdateAsync(originalDepartment);
            }
        }

        if (departmentId.HasValue)
        {
            var department = await _departmentRepository.GetByIdAsync(departmentId.Value);
            if (department == null)
            {
                await _logService.AddAsync($"更新用户部门失败：部门不存在 - {departmentId}");
                return Result<string>.Fail("部门不存在");
            }
            bool isDepartmentUpdated = department.AddUser(user);
            if (!isDepartmentUpdated)
            {
                await _logService.AddAsync($"更新用户部门失败：添加用户到部门失败 - 用户ID {userId}，部门ID {departmentId}");
                return Result<string>.Fail("部门ID更新失败");
            }
            await _departmentRepository.UpdateAsync(department);
        }
        else
        {
            user.DepartmentId = null;
        }

        bool isUserUpdated = user.UpdateUserDepartment(departmentId);
        if (!isUserUpdated)
        {
            await _logService.AddAsync($"更新用户部门失败：更新用户部门字段失败 - 用户ID {userId}");
            return Result<string>.Fail("部门ID更新失败");
        }

        await _userRepository.UpdateAsync(user);
        await _logService.AddAsync($"更新用户部门成功：用户 {user.UserName}，新部门ID {departmentId}");
        return Result<string>.Success("部门ID更新成功");
    }

    public async Task<Result<string>> UpdateUserInfoAsync(Guid userId, UserInfoDto userInfoDto)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"更新用户信息失败：用户不存在 - {userId}");
            return Result<string>.Fail("用户不存在");
        }

        bool isUserUpdated = user.UpdateUserInfo(userInfoDto.UserName, userInfoDto.Description);
        if (!isUserUpdated)
        {
            await _logService.AddAsync($"更新用户信息失败：更新失败 - {userId}");
            return Result<string>.Fail("用户信息更新失败");
        }

        await _userRepository.UpdateAsync(user);
        await _logService.AddAsync($"更新用户信息成功：{user.UserName}");
        return Result<string>.Success("用户信息更新成功");
    }

    public async Task<Result<string>> UpdateUserPwdAsync(Guid userId, UserPwdDto userPwdDto)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            await _logService.AddAsync($"更新用户密码失败：用户不存在 - {userId}");
            return Result<string>.Fail("用户不存在");
        }

        bool isUserUpdated = user.UpdateUserPwd(userPwdDto.Password);
        if (!isUserUpdated)
        {
            await _logService.AddAsync($"更新用户密码失败：更新失败 - {userId}");
            return Result<string>.Fail("用户密码更新失败");
        }

        await _userRepository.UpdateAsync(user);
        await _logService.AddAsync($"更新用户密码成功：{user.UserName}");
        return Result<string>.Success("用户密码更新成功");
    }
}